package cn.rtplay.esp32camcar.toolUtils;

import android.Manifest;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkRequest;
import android.net.NetworkSpecifier;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiNetworkSpecifier;
import android.os.PatternMatcher;
import android.provider.Settings;
import android.widget.Toast;

import androidx.core.app.ActivityCompat;

import java.util.List;

import cn.rtplay.esp32camcar.R;

public class NetworkUtils {

    private final static String TAG = "NetworkUtils";
    /**
     * 网络不可用
     */
    public static final int NO_NET_WORK = 0;
    /**
     * 是wifi连接
     */
    public static final int WIFI = 1;
    /**
     * 不是wifi连接
     */
    public static final int NO_WIFI = 2;

    private NetworkUtils() {
        /* cannot be instantiated */
        throw new UnsupportedOperationException("cannot be instantiated");
    }

    /**
     * 判断是否打开网络
     *
     * @param context context
     * @return true打开，false关闭
     */
    public static boolean isNetWorkAvailable(Context context) {
        boolean isAvailable = false;
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = null;
        if (cm != null) {
            networkInfo = cm.getActiveNetworkInfo();
        }
        if (networkInfo != null && networkInfo.isAvailable()) {
            isAvailable = true;
        }
        return isAvailable;
    }

    /**
     * 获取网络类型
     *
     * @param context context
     * @return 见类成员变量定义
     */
    public static int getNetWorkType(Context context) {
        if (!isNetWorkAvailable(context)) {
            return NetworkUtils.NO_NET_WORK;
        }
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

        if (cm != null) {
            NetworkInfo activeNetInfo = cm.getActiveNetworkInfo();
            if (activeNetInfo != null && activeNetInfo.getType() == ConnectivityManager.TYPE_WIFI)
                return NetworkUtils.WIFI;
            else
                return NetworkUtils.NO_WIFI;
        }
        return NetworkUtils.NO_WIFI;
    }

    /**
     * 判断当前网络是否为wifi
     *
     * @param context context
     * @return 如果为wifi返回true；否则返回false
     */
    @SuppressWarnings("static-access")
    public static boolean isWiFiConnected(Context context) {
        ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = null;
        if (manager != null) {
            networkInfo = manager.getActiveNetworkInfo();
        }
        if (networkInfo != null) {
            return networkInfo.getType() == manager.TYPE_WIFI;
        }
        return false;
    }

    /**
     * 判断MOBILE网络是否可用
     *
     * @param context context
     * @return 是否可用
     */
    public static boolean isMobileDataEnable(Context context) {
        ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        boolean isMobileDataEnable = false;
        if (manager != null) {
            NetworkInfo activeNetInfo = manager.getActiveNetworkInfo();
            if (activeNetInfo != null) {
                isMobileDataEnable = (activeNetInfo.getType() == ConnectivityManager.TYPE_MOBILE);
            }
        }
        return isMobileDataEnable;
    }

    /**
     * 判断wifi 是否可用
     *
     * @param context context
     * @return wifi是否使能
     */
    public static boolean isWifiDataEnable(Context context) {
        ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        boolean isWifiDataEnable = false;
        if (manager != null) {
            NetworkInfo activeNetInfo = manager.getActiveNetworkInfo();
            isWifiDataEnable = (activeNetInfo.getType() == ConnectivityManager.TYPE_WIFI);
        }
        return isWifiDataEnable;
    }

    public interface ConnectWifiCallBack {
        void connectResult(boolean connectResult);
    }

    /**
     * 通过热点用户名和密码连接热点
     *
     * @param context    上下文
     * @param wifiApName ssid
     * @param password   密码
     *                   //     * @param handler
     */
    public static int connectWifiApByNameAndPwd(Context context, String wifiApName, String
            password, ConnectWifiCallBack callBack) {
        LogUtil.v(TAG, "connectWifiApByNameAndPwd()");
        if (context == null || callBack == null) {
            LogUtil.i(TAG, "context == null || callBack == null");
            return -1;
        }
        WifiManager mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        //Andorid10.以下
        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.Q) {
            WifiConfiguration wifiNewConfiguration = getWifiConfig(context, wifiApName, password, true);//使用wpa2的wifi加密方式
            int newNetworkId = mWifiManager.addNetwork(wifiNewConfiguration);
            if (newNetworkId == -1) {
                LogUtil.e(TAG, "操作失败,需要您到手机wifi列表中取消对设备连接的保存");
                Toast.makeText(context, R.string.wifi_conn_error, Toast.LENGTH_SHORT).show();
                callBack.connectResult(false);
                return 0;
            }
            LogUtil.d(TAG, "newNetworkId is:" + newNetworkId);
            // 如果wifi权限没打开（1、先打开wifi，2，使用指定的wifi
            if (!mWifiManager.isWifiEnabled()) {
                mWifiManager.setWifiEnabled(true);
            }
            boolean enableNetwork = mWifiManager.enableNetwork(newNetworkId, true);
            if (!enableNetwork) {
                LogUtil.e(TAG, "切换到指定wifi失败");
                callBack.connectResult(false);
                return 0;
            }
            LogUtil.i(TAG, "切换到指定wifi成功");
            callBack.connectResult(true);
        } else {
            boolean isOpenWifi = mWifiManager.isWifiEnabled();
            if (!isOpenWifi) {
                LogUtil.d(TAG, "用户需要打开wifi开关");
                context.startActivity(new Intent(Settings.Panel.ACTION_INTERNET_CONNECTIVITY));
                callBack.connectResult(false);
                return 0;
            }
            NetworkSpecifier specifier =
                    new WifiNetworkSpecifier.Builder()
                            .setSsidPattern(new PatternMatcher(wifiApName, PatternMatcher.PATTERN_PREFIX))
                            .setWpa2Passphrase(password)
                            .build();

            NetworkRequest request =
                    new NetworkRequest.Builder()
                            .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                            .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                            .setNetworkSpecifier(specifier)
                            .build();

            ConnectivityManager connectivityManager = (ConnectivityManager)
                    context.getSystemService(Context.CONNECTIVITY_SERVICE);

            ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() {
                @Override
                public void onAvailable(Network network) {
                    // do success processing here..
                    LogUtil.v(TAG, "onAvailable success");
                    LogUtil.d(TAG, "network:" + network.toString());
                    callBack.connectResult(true);
                }

                @Override
                public void onUnavailable() {
                    // do failure processing here..
                    LogUtil.e(TAG, "onUnavailable fail");
                    callBack.connectResult(false);
                }
            };
            connectivityManager.requestNetwork(request, networkCallback);
        }
        return 0;
    }

    /**
     * 获取SSID
     *
     * @param context 上下文
     * @return WIFI 的SSID
     */
    public static String getWifiSSID(Context context) {
        WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        assert wifiManager != null;
        WifiInfo info = wifiManager.getConnectionInfo();
        return info.getSSID().replace("\"", "");
    }

    /**
     * wifi设置
     *
     * @param ssid     wifi ssid
     * @param pws      密码
     * @param isHasPws 是否有密码
     */
    private static WifiConfiguration getWifiConfig(Context context, String ssid, String pws,
                                                   boolean isHasPws) {
        WifiConfiguration config = new WifiConfiguration();
        config.allowedAuthAlgorithms.clear();
        config.allowedGroupCiphers.clear();
        config.allowedKeyManagement.clear();
        config.allowedPairwiseCiphers.clear();
        config.allowedProtocols.clear();
        config.SSID = "\"" + ssid + "\"";

        WifiConfiguration tempConfig = isExist(ssid, context);
        if (tempConfig != null) {
            WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
            wifiManager.removeNetwork(tempConfig.networkId);
        }
        if (isHasPws) {
            config.preSharedKey = "\"" + pws + "\"";
            config.hiddenSSID = true;
            config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
            config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
            config.status = WifiConfiguration.Status.ENABLED;
        } else {
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
        }
        return config;
    }

    /**
     * 得到配置好的网络连接
     *
     * @param ssid wifi ssid
     * @return 返回配置，或者null
     */
    private static WifiConfiguration isExist(String ssid, Context context) {
        WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(context, context.getString(R.string.no_x_permission, "ACCESS_FINE_LOCATION"), Toast.LENGTH_SHORT).show();
            return null;
        }
        List<WifiConfiguration> configs = wifiManager.getConfiguredNetworks();
        for (WifiConfiguration config : configs) {
            if (config.SSID.equals("\"" + ssid + "\"")) {
                return config;
            }
        }
        return null;
    }

    /**
     * 跳转到网络设置页面
     *
     * @param activity activity
     */
    public static void GoSetting(Activity activity) {
        Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
        activity.startActivity(intent);
    }

    /**
     * 打开网络设置界面
     */
    public static void openSetting(Activity activity) {
        Intent intent = new Intent("/");
        ComponentName cn = new ComponentName("com.android.settings", "com.android.settings.WirelessSettings");
        intent.setComponent(cn);
        intent.setAction("android.intent.action.VIEW");
        activity.startActivityForResult(intent, 0);
    }

}
